/**
 * Project Name:klpay
 * File Name:Calculator.java
 * Package Name:com.koalac.common.util
 * Date:2015年7月15日下午12:05:40
 * Copyright (c) 2015, All Rights Reserved.
 */

package com.agent.vpsserver.common.utils.digital;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * ClassName:NumberElement <br/>
 * Function: 数字计算元素。 <br/>
 * Reason: 确保java进行精度计算。 <br/>
 * Date: 2015年7月15日 下午12:05:40 <br/>
 *
 * @author yin
 * @see
 * @since JDK 1.7
 */
public class NumberElement {

    private BigDecimal decimal;

    private int SCALE = 4;

    private int TO_STRING_SCALE = 4;

    public BigDecimal getDecimal() {
        return decimal;
    }

    public void setDecimal(BigDecimal decimal) {
        this.decimal = decimal.setScale(SCALE, RoundingMode.FLOOR);
    }

    public NumberElement(BigDecimal decimal) {
        this.decimal = decimal.setScale(SCALE, RoundingMode.FLOOR);
    }

    public NumberElement(String decimal) {
        this.decimal = new BigDecimal(decimal).setScale(SCALE,
                RoundingMode.FLOOR);
    }

    public String toScaleString(int scale) {
        return this.getDecimal().setScale(scale, RoundingMode.HALF_UP)
                .toString();
    }

    public String toScaleString(int scale, RoundingMode mode) {
        return this.getDecimal().setScale(scale, mode)
                .toString();
    }

    @Override
    public String toString() {
        return decimal.setScale(TO_STRING_SCALE, RoundingMode.FLOOR).toString();
    }

    public NumberElement add(String num1, String num2) {
        return new NumberElement(new BigDecimal(num1).add(new BigDecimal(num2))
                .setScale(SCALE, RoundingMode.FLOOR));
    }

    public NumberElement add(String num1) {
        return new NumberElement(this.getDecimal().add(new BigDecimal(num1)));
    }

    public NumberElement add(NumberElement num1) {
        return new NumberElement(this.getDecimal().add(num1.getDecimal()));
    }

    public NumberElement sub(String num1, String num2) {
        return new NumberElement(new BigDecimal(num1).subtract(
                new BigDecimal(num2)).setScale(SCALE, RoundingMode.FLOOR));
    }

    public NumberElement sub(String num1) {
        return new NumberElement(this.getDecimal()
                .subtract(new BigDecimal(num1))
                .setScale(SCALE, RoundingMode.FLOOR));
    }

    public NumberElement sub(NumberElement num1) {
        return new NumberElement(this.getDecimal().subtract(num1.getDecimal())
                .setScale(SCALE, RoundingMode.FLOOR));
    }

    public NumberElement multiply(String num1, String num2) {
        return new NumberElement(new BigDecimal(num1).multiply(
                new BigDecimal(num2)).setScale(SCALE, RoundingMode.FLOOR));
    }

    public NumberElement multiply(String num1) {
        return new NumberElement(this.getDecimal()
                .multiply(new BigDecimal(num1))
                .setScale(SCALE, RoundingMode.FLOOR));
    }

    public NumberElement multiply(NumberElement num1) {
        return new NumberElement(this.getDecimal().multiply(num1.getDecimal())
                .setScale(SCALE, RoundingMode.FLOOR));
    }

    public NumberElement divide(String num1, String num2) {
        return new NumberElement(new BigDecimal(num1).divide(
                new BigDecimal(num2), SCALE, RoundingMode.FLOOR));
    }

    public NumberElement divide(String num1) {
        return new NumberElement(this.getDecimal().divide(new BigDecimal(num1), SCALE, RoundingMode.FLOOR));
    }

    public NumberElement divide(NumberElement num1) {
        return new NumberElement(this.getDecimal().divide(num1.getDecimal(), SCALE, RoundingMode.FLOOR));
    }

    /**
     * 除法，divide里面需要包含一个精度，否则出现无限小数时会报错
     *
     * @param num1
     * @return
     */
    public NumberElement division(String num1) {
        return new NumberElement(this.getDecimal().divide(new BigDecimal(num1), SCALE, RoundingMode.FLOOR));
    }

    public boolean eqOrG(String num1) {
        return decimal.compareTo(new BigDecimal(num1)) >= 0;
    }

    public boolean eqOrG(NumberElement numberElement) {
        return decimal.compareTo(numberElement.getDecimal()) >= 0;
    }

    public boolean eqOrL(String num1) {
        return decimal.compareTo(new BigDecimal(num1)) <= 0;
    }

    public boolean l(String num1) {
        return decimal.compareTo(new BigDecimal(num1)) < 0;
    }

    public boolean eq(String num1) {
        return decimal.compareTo(new BigDecimal(num1)) == 0;
    }

    public boolean g(String num1) {
        return decimal.compareTo(new BigDecimal(num1)) > 0;
    }

    public boolean eqOrL(NumberElement numberElement) {
        return decimal.compareTo(numberElement.getDecimal()) <= 0;
    }

    public boolean l(NumberElement numberElement) {
        return decimal.compareTo(numberElement.getDecimal()) < 0;
    }

    public boolean eq(NumberElement numberElement) {
        return decimal.compareTo(numberElement.getDecimal()) == 0;
    }

    public boolean g(NumberElement numberElement) {
        return decimal.compareTo(numberElement.getDecimal()) > 0;
    }

    public boolean gtz() {
        return decimal.compareTo(new BigDecimal("0")) > 0;
    }

    public boolean ltz() {
        return decimal.compareTo(new BigDecimal("0")) < 0;
    }

    public boolean eqz() {
        return decimal.compareTo(new BigDecimal("0")) == 0;
    }
}
